<template>
  <view
    class="c-image"
    ref="imgRef"
    :class="ggclass"
    :style="{ width, height, borderRadius: radius, background }"
    @click="onclick"
  >
    <image
      :style="{ width, height }"
      :src="srcs"
      :mode="modes"
      @load="load"
      @error="error"
      show-menu-by-longpress
    >
    </image>
    <!-- #ifndef MP-TOUTIAO -->
    <c-loading
      class="loding"
      isOpenPattern
      :size="lodingS"
      :loading="isloding"
    ></c-loading>
    <!-- #endif -->
  </view>
</template>

<script setup lang="ts">
import propsMixin from "../mixins/props/index";
//@ts-ignore
import { error as errorBase64 } from "../../static/img/base64.js";
import { imgFilter as filter } from "../ways/filter";
//@ts-ignore
import { imgPreview } from "../ways/img.js";
import {
  defineProps,
  reactive,
  watch,
  computed,
  onMounted,
  getCurrentInstance,
  toRefs,
} from "vue";
const { proxy } = getCurrentInstance() as any;
const props = defineProps({
  ...propsMixin.props,
  src: {
    type: String,
    default: "",
  },
  errorSrc: {
    type: String,
    default: errorBase64,
  },
  mode: {
    type: String,
    default: "",
  },
  width: {
    type: String,
    default: "",
  },
  height: {
    type: String,
    default: "",
  },
  radius: {
    type: String,
    default: "",
  },
  isPreview: {
    type: Boolean,
    default: false,
  },
  lazy: {
    type: Boolean,
    default: false,
  },
  lodingSize: {
    type: [String, Number],
    default: "",
  },
});
const state = reactive({
  lazySrc: "",
  ladingVal: "",
  isloding: true,
  imgUrl: "",
});
const { isloding } = toRefs(state);
const srcs = computed({
  get() {
    let src = props.lazy ? state.lazySrc : state.imgUrl;
    return filter(src);
  },
  set(val) {
    state.imgUrl = val;
    state.lazySrc = val;
  },
});
const authenticate = () => {
  setTimeout(() => {
    if (!props.src) {
      srcs.value = " ";
    }
  }, 10000);
};
watch(
  () => props.src,
  (n) => {
    if (!props.lazy) {
      authenticate();
    }
    srcs.value = n || "";
  },
  { immediate: true }
);

const modes = computed(() => {
  if (props.mode) return;
  if (props.width && !props.height) return "widthFix";
  if (props.height && !props.width) return "heightFix";
  return "scaleToFill";
});


const lodingS = computed(() => {
  if (props.lodingSize) return props.lodingSize;
  let unit = String(props.width).match(/[a-z|A-Z|'%']+/gi);
  return (parseInt(props.width as string) / 2).toString() + unit;
});
onMounted(() => {
  if (props.lazy) {
    observer(".c-image", () => {
      state.lazySrc = props.src;
      authenticate();
    });
  }
});


const observer = (node: string, callback: Function) => {
  let observer = uni.createIntersectionObserver(this);
  let ob = observer.relativeToViewport();
  ob.observe(node, (res) => {
    callback(res);
    observer.disconnect();
  });
};
const onclick = (e: Event) => {
  if (props.isPreview) {
    imgPreview(props.src);
  }
  proxy.$emit("click", e);
  proxy.$emit("tap", e);
};
const load = () => {
  state.isloding = false;
};
const error = () => {
  state.isloding = false;
  srcs.value = props.errorSrc as string;
};
</script>

<style lang="scss" scoped>
.c-image {
  display: inline-flex;
  overflow: hidden;
  justify-content: center;
  align-items: center;
  box-sizing: border-box;
  position: relative;
  font-size: 0rpx;
  -webkit-text-size-adjust: none;
  letter-spacing: normal;
  word-spacing: normal;
  vertical-align: top;

  .loding {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
  }
}
</style>